﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
using PhoneBilling.Models;
using System.Configuration;
using System.IO;

namespace PhoneBilling
{
    public static class AutoBackupMgt
    {
        private static Object syncObj = new object();

        private static Thread thread;

        public static void Start()
        {
            lock (syncObj)
            {
                if (thread != null)
                {
                    thread.Abort();
                }
            }
            thread = new Thread(threadStart);
            thread.Start();
        }

        private static void threadStart()
        {
            SanDiDbsEntities entities = new SanDiDbsEntities();
            var isAutoBackup = (from s in entities.SystemData
                                where s.Name == "IsAutoBackup"
                                select s).SingleOrDefault();
            if (isAutoBackup != null && isAutoBackup.Value.Trim() == "True")
            {
                string path = (from s in entities.SystemData
                                    where s.Name == "AutoBackupPath"
                                    select s.Value).SingleOrDefault();

                var backupCycle = (from s in entities.SystemData
                                   where s.Name == "BackupCycle"
                                   select s.Value).SingleOrDefault();

                DateTime time;
                var backupTime = (from s in entities.SystemData
                                  where s.Name == "BackupTime"
                                  select s).SingleOrDefault();
                if (backupTime == null)
                    time = new DateTime(2000, 1, 1);
                else
                    time = Convert.ToDateTime(backupTime.Value);

                var cycleValue = (from s in entities.SystemData
                                  where s.Name == "BackupCycleValue"
                                  select s.Value).SingleOrDefault();
                DateTime nextTime = DateTime.MinValue;
                DateTime now = DateTime.Now;
                switch (backupCycle)
                { 
                    case "按月备份":
                        int day = Convert.ToInt32(cycleValue);
                        
                        nextTime = new DateTime(now.Year, now.Month, day, time.Hour, time.Minute, time.Second);
                        if (nextTime <= now)
                            nextTime= nextTime.AddMonths(1);
                        break;
                    case "按周备份":
                        int dayofweek = 0;
                        switch (cycleValue.Trim())
                        { 
                            case "星期一":
                                dayofweek = 1;
                                break;
                            case "星期二":
                                dayofweek = 2;
                                break;
                            case "星期三":
                                dayofweek = 3;
                                break;
                            case "星期四":
                                dayofweek = 4;
                                break;
                            case "星期五":
                                dayofweek = 5;
                                break;
                            case "星期六":
                                dayofweek = 6;
                                break;
                            case "星期日":
                                dayofweek = 0;
                                break;
                        }
                        int days = dayofweek - (int)now.DayOfWeek;
                        if (days < 0)
                            days += 7;
                        nextTime = new DateTime(now.Year, now.Month, now.Day, time.Hour, time.Minute, time.Second);
                        nextTime = nextTime.AddDays(days);
                        if (nextTime <= now)
                            nextTime = nextTime.AddDays(7);
                        break;

                    case "按日备份":
                        nextTime = new DateTime(now.Year, now.Month, now.Day, time.Hour, time.Minute, time.Second);
                        if (nextTime <= now)
                            nextTime= nextTime.AddDays(1);
                        break;
                }

                if (nextTime != DateTime.MinValue) 
                {
                    Thread.Sleep((nextTime - now));
                }

                lock (syncObj)
                {
                    Type sqlServerType = Type.GetTypeFromProgID("sqldmo.SQLServer");
                    sqldmo.SQLServer srv = (sqldmo.SQLServer)Activator.CreateInstance(sqlServerType);

                    string server = ConfigurationManager.AppSettings["Server"].ToString();
                    string user = ConfigurationManager.AppSettings["User"].ToString();
                    string password = ConfigurationManager.AppSettings["Password"].ToString();
                    string databse = ConfigurationManager.AppSettings["DataBase"].ToString();



                    Type backupType = Type.GetTypeFromProgID("sqldmo.Backup");
                    sqldmo.Backup backup = (sqldmo.Backup)Activator.CreateInstance(backupType);

                    try
                    {
                        srv.Connect(server, user, password);

                        backup.Action = 0;
                        backup.Initialize = true;
                        string fileName = string.Format("{0}.bak", DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"));
                        backup.Files = string.Format("{1}/{0}", fileName,path);
                        backup.Database = databse;
                        backup.SQLBackup(srv);

                        FileStream stream = new FileStream(backup.Files, FileMode.Open, FileAccess.Read);
                        byte[] b = new byte[stream.Length];
                        stream.Position = 0;
                        stream.Read(b, 0, b.Length);
                        stream.Close();

                    }
                    catch (Exception ex)
                    {
                    }
                    finally
                    {
                        srv.DisConnect();
                    }
                }

                threadStart();
            }
        }
    }
}